package com.sanyue.codingsettlement.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sanyue.codingsettlement.common.ErrorCode;
import com.sanyue.codingsettlement.constant.RedisLuaScriptConstant;
import com.sanyue.codingsettlement.constant.ThumbConstant;
import com.sanyue.codingsettlement.exception.BusinessException;
import com.sanyue.codingsettlement.exception.ThrowUtils;
import com.sanyue.codingsettlement.mapper.PostThumbMapper;
import com.sanyue.codingsettlement.model.entity.Post;
import com.sanyue.codingsettlement.model.entity.PostThumb;
import com.sanyue.codingsettlement.model.entity.User;
import com.sanyue.codingsettlement.model.enums.LuaStatusEnum;
import com.sanyue.codingsettlement.service.PostService;
import com.sanyue.codingsettlement.service.PostThumbService;

import javax.annotation.Resource;

import com.sanyue.codingsettlement.service.UserService;
import com.sanyue.codingsettlement.utils.RedisKeyUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Arrays;

/**
 * 帖子点赞服务实现
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://yupi.icu">编程导航知识星球</a>
 */
@Service
@RequiredArgsConstructor
public class PostThumbServiceImpl extends ServiceImpl<PostThumbMapper, PostThumb>
        implements PostThumbService {

    @Resource
    private PostService postService;


    @Resource
    private UserService userService;

    //编程式事务
    private final TransactionTemplate transactionTemplate;


    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 点赞
     *
     * @param postId
     * @param loginUser
     * @return
     */
    @Override
    public Boolean doPostThumb(Long postId, User loginUser) {
        //1.参数校验，前面已经校验完毕了，判断实体是否存在
        Post post = postService.getById(postId);
        ThrowUtils.throwIf(post == null, ErrorCode.NOT_FOUND_ERROR, "帖子不存在");
        // 指定Lua脚本
        // 是否点赞  点赞记录 临时日志记录
        String timeSlice = getTimeSlice();
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice);
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId());
        // 执行 Lua 脚本
        long result = redisTemplate.execute(
                RedisLuaScriptConstant.THUMB_SCRIPT,
                Arrays.asList(tempThumbKey, userThumbKey),
                loginUser.getId(),
                postId
        );
        if (LuaStatusEnum.FAIL.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "您已经点赞过了");
        }
        return LuaStatusEnum.SUCCESS.getValue() == result;
    }

    /**
     * 取消点赞
     *
     * @param postId
     * @param loginUser
     * @return
     */
    @Override
    public Boolean unDoPostThumb(Long postId, User loginUser) {
        //1.参数校验，前面已经校验完毕了，判断实体是否存在
        Post post = postService.getById(postId);
        ThrowUtils.throwIf(post == null, ErrorCode.NOT_FOUND_ERROR, "帖子不存在");
        // 指定Lua脚本
        // 是否点赞  删除点赞记录 临时日志记录
        String timeSlice = getTimeSlice();
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice);
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId());
        // 执行 Lua 脚本
        long result = redisTemplate.execute(
                RedisLuaScriptConstant.UNTHUMB_SCRIPT,
                Arrays.asList(tempThumbKey, userThumbKey),
                loginUser.getId(),
                postId
        );
        if (LuaStatusEnum.FAIL.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "您还未点赞");
        }
        return LuaStatusEnum.SUCCESS.getValue() == result;
    }

    /**
     * 用户是否点过赞
     *
     * @param postId
     * @param userId
     * @return
     */
    @Override
    public Boolean hasThumb(Long postId, Long userId) {
        return redisTemplate.opsForHash().hasKey(ThumbConstant.USER_THUMB_KEY_PREFIX + userId, postId.toString());
    }


    /**
     * 获取当前时间前最近的整数秒
     *
     * @return
     */
    private String getTimeSlice() {
        DateTime nowDate = DateUtil.date();
        // 获取到当前时间前最近的整数秒，比如当前 11:20:23 ，获取到 11:20:20
        return DateUtil.format(nowDate, "HH:mm:") + (DateUtil.second(nowDate) / 10) * 10;
    }

}




